Type.registerNamespace('Ajax.Logging');

Ajax.Logging.WebServiceListener = function(lineSeparator, servicePath, serviceMethod, interval)
{
    this._servicePath = servicePath;
    this._serviceMethod = serviceMethod;
    this._interval = interval;

    this._timerHandle = null;
    this._logQueue = new Array();

    this._timerHandler = null;
    this._successHandler = null;
    this._failureHandler = null;
    this._unloadHandler = null;

    Ajax.Logging.WebServiceListener.initializeBase(this, [lineSeparator]);

    this._hookUnload();
    this._startTimer();
}

Ajax.Logging.WebServiceListener.prototype =
{
    dispose : function()
    {
        this._stopTimer();
        delete this._timerHandle;

        if (this._unloadHandler != null)
        {
            $removeHandler(window, 'unload', this._unloadHandler);
            delete this._unloadHandler;
        }

        if (this._timerHandler != null)
        {
            delete this._timerHandler;
        }

        if (this._successHandler != null)
        {
            delete this._successHandler;
        }

        if (this._failureHandler != null)
        {
            delete this._failureHandler;
        }

        delete this._logQueue;

        Ajax.Logging.WebServiceListener.callBaseMethod(this, 'dispose');
    },

    publishException: function(errorCode, exception, environmentInfo)
    {
        var exceptionInfo = new Object();

        exceptionInfo.Code = errorCode;

        if (typeof exception.get_exceptionType != 'undefined')
        {
            exceptionInfo.Message = exception.get_message();
            exceptionInfo.Type = exception.get_exceptionType();
            exceptionInfo.StackTrace = exception.get_stackTrace();
        }
        else
        {
            exceptionInfo.Message = exception.message;
            exceptionInfo.Type = exception.name;
            exceptionInfo.Description = exception.description;

            if (typeof exception.lineNumber != 'undefined')
            {
                exceptionInfo.LineNumber = exception.lineNumber;
            }
        }

        exceptionInfo.Url = environmentInfo.url;
        exceptionInfo.Referrer = environmentInfo.referrer;
        exceptionInfo.Scripts = environmentInfo.scripts;

        Array.add(this._logQueue, exceptionInfo);
    },

    _startTimer : function()
    {
        this._stopTimer();
        this._timerHandler = Function.createDelegate(this, this._log);
        this._timerHandle = setTimeout(this._timerHandler, this._interval);
    },

    _stopTimer : function()
    {
        if (this._timerHandle != null)
        {
            clearTimeout(this._timerHandle);
            this._timerHandle = null;
        }
    },

    _log : function()
    {
        if (this._logQueue.length > 0)
        {
            var logging = new Array();
            Array.addRange(logging, this._logQueue);

            this._successHandler = Function.createDelegate(this, this._onSuccess);
            this._failureHandler = Function.createDelegate(this, this._onFail);
            this._callServer(logging, this._successHandler, this._failureHandler, logging);
        }
        else
        {
            this._startTimer();
        }
    },

    _onSuccess : function(success, logged)
    {
        if (success)
        {
            for(var i = 0; i < logged.length; i++)
            {
                Array.remove(this._logQueue, logged[i]);
            }

            this._startTimer();
        }
    },

    _onFail : function()
    {
        this._startTimer();
    },

    _hookUnload : function()
    {
        this._unloadHandler = Function.createDelegate(this, this._onUnload);
        $addHandler(window, 'unload', this._unloadHandler);
    },

    _onUnload : function()
    {
        this._stopTimer();

        if (this._logQueue.length > 0)
        {
            this._callServer(this._logQueue, null, null, null);
        }
    },

    _callServer : function(logQueue, successHandler, failureHandler, context)
    {
        Sys.Net.WebServiceProxy.invoke(this._servicePath, this._serviceMethod, false, {exceptions: logQueue}, successHandler, failureHandler, context);
    }
}

Ajax.Logging.WebServiceListener.registerClass('Ajax.Logging.WebServiceListener', Ajax.Logging.BaseListener);

if (typeof(Sys) != 'undefined')
{
    Sys.Application.notifyScriptLoaded();
}